﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ibba.src.global;
using ibba.src.norisk.Contracts;
using ibba.src.DataAccess;
using System.Data;

namespace ibba.src.norisk.DataAccess
{
    public class DeParaTipoLimiteDB : DataAccessBase
    {
        #region Metodos Publicos

        #region Tipo Limite

        /// <summary>
        /// Recupera dos dominios de tipo limite;
        /// </summary>
        /// <returns>Colecao de tipos de limites</returns>
        public List<TipoLimite> ObterListaTipoLimite()
        {
            List<TipoLimite> retorno = new List<TipoLimite>();
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                DataSet ds = db.ExecuteDataset(CommandType.StoredProcedure, "SRCP_OBTER_LISTA_TIPO_LIMITE", new List<IDataParameter>());

                #region Tabelas

                DataTable dtTipoLimite = ds.Tables[0];
                DataTable dtEstrategia = ds.Tables[1];
                DataTable dtProduto = ds.Tables[2];

                #endregion

                #region ListaEstrategias

                List<Estrategia> estrategias = new List<Estrategia>();
                foreach (DataRow item in dtEstrategia.Rows)
                {
                    estrategias.Add(new Estrategia()
                    {
                        Acao = Estrategia.TipoAcao.NONE,
                        Estado = Estrategia.TipoEstado.ANTIGO,
                        CodTipoLimite = Convert.ToInt32(item["IDT_SUB_AREA_INSL_CRED"]),
                        CodDePara = Convert.ToInt32(item["ID_DEPARA_TIPO_LIMITE_ESTRATEGIA"]),
                        Codigo = item["ID_ESTRATEGIA"].ToString(),
                        Descricao = item["DS_ESTRATEGIA"].ToString()
                    });
                } 

                #endregion

                #region ListaProdutos

                List<ProdutoItau> produtos = new List<ProdutoItau>();
                foreach (DataRow item in dtProduto.Rows)
                {
                    produtos.Add(new ProdutoItau()
                    {
                        Acao = ProdutoItau.TipoAcao.NONE,
                        Estado = ProdutoItau.TipoEstado.ANTIGO,
                        CodTipoLimite = Convert.ToInt32(item["IDT_SUB_AREA_INSL_CRED"]),
                        CodDePara = Convert.ToInt32(item["ID_DEPARA_TIPO_LIMITE_PRODUTO"]),
                        Codigo = item["CD_PRODUTO_ITAU"].ToString(),
                        Descricao = item["DS_PRODUTO_NC"].ToString()
                    });
                }
                
                #endregion

                foreach (DataRow item in dtTipoLimite.Rows)
                {
                    int codigo = Convert.ToInt32(item["IDT_SUB_AREA_INSL_CRED"]);
                    retorno.Add(new TipoLimite()
                    {
                        CodTipoLimite = codigo,
                        DscTipoLimite = item["NOM_SUB_AREA_INSL_CRED"].ToString(),
                        Ativo = Convert.ToBoolean(item["IND_ATIV_INAT"]),
                        Estrategias = estrategias.Where(x => x.CodTipoLimite == codigo).Count() > 0 ? estrategias.Where(x => x.CodTipoLimite == codigo).ToList() : new List<Estrategia>(),
                        ProdutosItau = produtos.Where(x => x.CodTipoLimite == codigo).Count() > 0 ? produtos.Where(x => x.CodTipoLimite == codigo).ToList() : new List<ProdutoItau>()
                    });
                }

            }
            return retorno;
        }

        #endregion

        #region Produto

        /// <summary>
        /// Recupera lista de estrategias atreladas ao tipo de limite;
        /// </summary>
        /// <param name="codTipoLimite">Chave de identificacao do tipo de limite</param>
        /// <returns>Colecao de estrategias</returns>
        public List<ProdutoItau> ObterListaProdutoPorCodigoTipoLimite(int codTipoLimite)
        {
            List<ProdutoItau> retorno = new List<ProdutoItau>();
            List<IDataParameter> parametros = new List<IDataParameter>();
            parametros.Add(AcessoDadosHelper.CriarParametro("@pID_LIMITE_MESA", DbType.Int32, codTipoLimite));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_PRODUTO_POR_LIMITE", parametros))
                {
                    while (reader.Read())
                    {
                        retorno.Add(new ProdutoItau()
                        {
                            CodDePara = Convert.ToInt32(reader["ID_DEPARA_TIPO_LIMITE_PRODUTO"]),
                            Codigo = reader["CD_PRODUTO_ITAU"].ToString(),
                            Descricao = reader["DS_PRODUTO_NC"].ToString()
                        });
                    }
                }
            }
            return retorno;
        }

        /// <summary>
        /// Persiste colecao de produtos
        /// </summary>
        /// <param name="produtos">lista de produtos a serem persistidos</param>
        /// <returns>Retorna lista de produtos ja atrelados [caso exista]</returns>
        public List<TipoLimite> InserirProdutos(List<ProdutoItau> produtos)
        {
            List<TipoLimite> retorno = new List<TipoLimite>();
            string xml = global.Serializer.Serialize<List<ProdutoItau>>(produtos);
            List<IDataParameter> parametros = new List<IDataParameter>();
            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML_PRODUTO_ITAU", DbType.Xml, xml));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_INSERIR_PRODUTO_POR_LIMITE", parametros))
                {
                    while (reader.Read())
                    {
                        TipoLimite limite = retorno.Find(x => x.CodTipoLimite == Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]));
                        if (limite == null)
                        {
                            limite = new TipoLimite()
                            {
                                CodTipoLimite = Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]),
                                DscTipoLimite = reader["NOM_SUB_AREA_INSL_CRED"].ToString(),
                            };
                            limite.ProdutosItau = new List<ProdutoItau>();
                        }
                        limite.ProdutosItau.Add(new ProdutoItau()
                        {
                            CodDePara = Convert.ToInt32(reader["ID_DEPARA_TIPO_LIMITE_PRODUTO"]),
                            Codigo = reader["CD_PRODUTO_ITAU"].ToString(),
                            Descricao = reader["DS_PRODUTO_NC"].ToString()
                        });
                        retorno.Add(limite);
                    }
                }
            }
            return retorno;
        }

        /// <summary>
        /// Realiza a exclusao dos produtos;
        /// </summary>
        /// <param name="produtos">Lista de produtos a serem excluidos</param>
        public void ExcluirProdutos(List<ProdutoItau> produtos)
        {
            string xml = global.Serializer.Serialize<List<ProdutoItau>>(produtos);
            List<IDataParameter> parametros = new List<IDataParameter>();
            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML_PRODUTO_ITAU", DbType.Xml, xml));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                db.ExecuteNonQuery(CommandType.StoredProcedure, "SRCP_EXCLUIR_PRODUTO_POR_LIMITE", parametros);
            }
        }

        /// <summary>
        /// Recupera a lista de produtos Itau atraves da descricao
        /// </summary>
        /// <param name="descricao">descricao do produto Itau para a realizacao de busca</param>
        /// <returns>Lista de produto Itau</returns>
        public List<ProdutoItau> ObterListaProdutoPorDescricao(string descricao)
        {
            List<ProdutoItau> produtos = new List<ProdutoItau>();
            List<IDataParameter> parametros = new List<IDataParameter>();

            if (!string.IsNullOrEmpty(descricao))
                parametros.Add(AcessoDadosHelper.CriarParametro("@pDS_PRODUTO", DbType.String, descricao));
            else
                parametros.Add(AcessoDadosHelper.CriarParametro("@pDS_PRODUTO", DbType.String, null));

            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_PRODUTO_POR_DESCRICAO", parametros))
                {
                    while (reader.Read())
                        produtos.Add(ConstruirProduto(reader));
                }
            }

            return produtos;
        }

        #endregion

        #region Estrategia

        /// <summary>
        /// Recupera lista de estrategias atreladas ao tipo de limite;
        /// </summary>
        /// <param name="codTipoLimite">Chave de identificacao do tipo de limite</param>
        /// <returns>Colecao de estrategias</returns>
        public List<Estrategia> ObterListaEstrategiaPorCodigoTipoLimite(int codTipoLimite)
        {
            List<Estrategia> retorno = new List<Estrategia>();
            List<IDataParameter> parametros = new List<IDataParameter>();
            parametros.Add(AcessoDadosHelper.CriarParametro("@pID_LIMITE_MESA", DbType.Int32, codTipoLimite));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_ESTRATEGIA_POR_LIMITE", parametros))
                {
                    while (reader.Read())
                    {
                        retorno.Add(new Estrategia()
                        {
                            CodDePara = Convert.ToInt32(reader["ID_DEPARA_TIPO_LIMITE_ESTRATEGIA"]),
                            Codigo = reader["ID_ESTRATEGIA"].ToString(),
                            Descricao = reader["DS_ESTRATEGIA"].ToString()
                        });
                    }
                }
            }
            return retorno;
        }

        /// <summary>
        /// Persiste a lista de estrategias;
        /// </summary>
        /// <param name="estrategias">lista de produtos a serem persistidos</param>
        /// <returns>Retorna lista de estrategias ja atrelados [caso exista]</returns>
        public List<TipoLimite> InserirEstrategias(List<Estrategia> estrategias)
        {
            List<TipoLimite> retorno = new List<TipoLimite>();            
            List<IDataParameter> parametros = new List<IDataParameter>();

            string xml = global.Serializer.Serialize<List<Estrategia>>(estrategias);

            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML_ESTRATEGIA", DbType.Xml, xml));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_INSERIR_ESTRATEGIA_POR_LIMITE", parametros))
                {
                    while (reader.Read())
                    {
                        TipoLimite limite = retorno.Find(x => x.CodTipoLimite == Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]));
                        if (limite == null)
                        {
                            limite = new TipoLimite()
                            {
                                CodTipoLimite = Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]),
                                DscTipoLimite = reader["NOM_SUB_AREA_INSL_CRED"].ToString(),
                            };
                            limite.Estrategias = new List<Estrategia>();
                        }
                        limite.Estrategias.Add(new Estrategia()
                        {
                            CodDePara = Convert.ToInt32(reader["ID_DEPARA_TIPO_LIMITE_ESTRATEGIA"]),
                            Codigo = reader["ID_ESTRATEGIA"].ToString(),
                            Descricao = reader["DS_ESTRATEGIA"].ToString()
                        });
                        retorno.Add(limite);
                    }
                }
            }
            return retorno;
        }

        /// <summary>
        /// Realiza a exclusao das estrategias;
        /// </summary>
        /// <param name="produtos">Lista de estrategias a serem excluidas</param>
        public void ExcluirEstrategias(List<Estrategia> estrategias)
        {
            string xml = global.Serializer.Serialize<List<Estrategia>>(estrategias);
            List<IDataParameter> parametros = new List<IDataParameter>();
            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML_ESTRATEGIA", DbType.Xml, xml));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                db.ExecuteNonQuery(CommandType.StoredProcedure, "SRCP_EXCLUIR_ESTRATEGIA_POR_LIMITE", parametros);
            }
        }

        /// <summary>
        /// Recupera lista de estrategias
        /// </summary>
        /// <param name="descricao">descricao da estrategia para realizacao de busca</param>
        /// <returns>Lista de estrategia</returns>
        public List<Estrategia> ObterListaEstrategiaPorDescricao(string descricao)
        {
            List<Estrategia> estrategias = new List<Estrategia>();
            List<IDataParameter> parametros = new List<IDataParameter>();

            if (!string.IsNullOrEmpty(descricao))
                parametros.Add(AcessoDadosHelper.CriarParametro("@pDS_ESTRATEGIA", DbType.String, descricao));
            else
                parametros.Add(AcessoDadosHelper.CriarParametro("@pDS_ESTRATEGIA", DbType.String, null));

            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_ESTRATEGIA_POR_DESCRICAO", parametros))
                {
                    while (reader.Read())
                        estrategias.Add(ConstruirEstrategia(reader));
                }
            }
            return estrategias;
        }

        #endregion

        #region AreaInstitucional

        //public List<AreaInstitucional> ObterListaAreaInstPorCodigoTipoLimite(int codTipoLimite)
        //{
        //    var retorno = new List<AreaInstitucional>();
        //    var parametros = new List<IDataParameter>();

        //    parametros.Add(AcessoDadosHelper.CriarParametro("@pID_LIMITE_MESA", DbType.Int32, codTipoLimite));
        //    using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
        //    {
        //        using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_AREA_INST_POR_LIMITE", parametros))
        //        {
        //            while (reader.Read())
        //            {
        //                retorno.Add(new AreaInstitucional()
        //                {
        //                    CodDePara = Convert.ToInt32(reader["ID_DEPARA_TIPO_LIMITE_ESTRATEGIA"]),
        //                    Codigo = reader["ID_ESTRATEGIA"].ToString(),
        //                    Descricao = reader["DS_ESTRATEGIA"].ToString()
        //                });
        //            }
        //        }
        //    }
        //    return retorno;
        //}

        public List<TipoLimite> InserirAreaInstitucional(List<AreaInstitucional> areas)
        {
            var retorno = new List<TipoLimite>();
            var parametros = new List<IDataParameter>(); 

            string xml = global.Serializer.Serialize<List<AreaInstitucional>>(areas);
            
            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML", DbType.Xml, xml));
            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_INSERIR_DEPARA_AREA_INSTITUCIONAL", parametros))
                {
                    while (reader.Read())
                    {
                        TipoLimite limite = retorno.Find(x => x.CodTipoLimite == Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]));
                        if (limite == null)
                        {
                            limite = new TipoLimite()
                            {
                                CodTipoLimite = Convert.ToInt32(reader["IDT_SUB_AREA_INSL_CRED"]),
                                DscTipoLimite = reader["NOM_SUB_AREA_INSL_CRED"].ToString(),
                            };
                            limite.AreasInstitucionais = new List<AreaInstitucional>();
                        }
                        
                        limite.AreasInstitucionais.Add(new AreaInstitucional()
                        {
                            CodDePara = Convert.ToInt32(reader["IDT_ASSOC_TIP_LIM_AREA_INST"].ToString()),
                            Codigo = (string)base.ObterValor(reader, "COD_AREA_INST"),
                            Descricao = reader["DS_AREA_INST"].ToString()                         
                        });
                        retorno.Add(limite);
                    }
                }
            }
            return retorno;
        }

        public void ExcluirAreaInstitucional(List<AreaInstitucional> areas)
        {
            var parametros = new List<IDataParameter>();
            string xml = global.Serializer.Serialize<List<AreaInstitucional>>(areas);
            
            parametros.Add(AcessoDadosHelper.CriarParametro("@pXML", DbType.Xml, xml));

            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                db.ExecuteNonQuery(CommandType.StoredProcedure, "SRCP_EXCLUIR_DEPARA_AREA_INSTITUCIONAL", parametros);
            }
        }

        public List<AreaInstitucional> ObterListaAreaInstPorDescricao(string descricao)
        {
            var retorno = new List<AreaInstitucional>();
            var parametros = new List<IDataParameter>();

            if (!string.IsNullOrEmpty(descricao))
                parametros.Add(AcessoDadosHelper.CriarParametro("@DS_AREA_INSTITUCIONAL", DbType.String, descricao));
            else
                parametros.Add(AcessoDadosHelper.CriarParametro("@DS_AREA_INSTITUCIONAL", DbType.String, null));

            using (AcessoDadosHelper db = new AcessoDadosHelper(GlobalInfo.SISTEMA, GlobalInfo.LOCAL))
            {
                using (IDataReader reader = db.ExecuteReader(CommandType.StoredProcedure, "SRCP_OBTER_DEPARA_AREA_INSTITUCIONAL", parametros))
                {
                    while (reader.Read())
                        retorno.Add(ConstruirAreaInstitucional(reader));
                }
            }
            return retorno;
        }

        #endregion

        #endregion

        #region Metodos Privados

        #region Produto

        private ProdutoItau ConstruirProduto(IDataReader reader)
        {
            return new ProdutoItau()
            {
                Codigo = reader["ID_CHAVE"].ToString(),
                Descricao = reader["DS_PRODUTO_NC"].ToString()
            };
        }

        #endregion

        #region Estrategia

        private Estrategia ConstruirEstrategia(IDataReader reader)
        {
            return new Estrategia()
            {
                Codigo = reader["ID_ESTRATEGIA"].ToString(),
                Descricao = reader["DS_ESTRATEGIA"].ToString()
            };
        }

        #endregion

        #region Estrategia
       
        private AreaInstitucional ConstruirAreaInstitucional(IDataReader reader)
        {
            return new AreaInstitucional()
            {
                Codigo =  reader["ID_AREA_INST"].ToString(),
                Descricao = reader["DS_AREA_INST"].ToString()
            };
        }

        #endregion

        #endregion
    }
}
